﻿#include "chatserver.h"
#include "chatclient.h"

class ChatServerPrivate {
public:
  QString myServerAddress = "192.168.1.177";
  int myPort = 5555;

public:
  QList<ChatClient *> tcpClients;
};

ChatServer::ChatServer(QObject *parent)
    : QTcpServer(parent), serverPrivate(new ChatServerPrivate) {
  qRegisterMetaType<QByteArray>("QByteArray &");
}

ChatServer::~ChatServer() {}

bool ChatServer::startListen() {
  if (this->isListening()) {
    qDebug() << "is listening";
    return false;
  }

  this->listen(QHostAddress(serverPrivate->myServerAddress),
               serverPrivate->myPort);
  qDebug() << "start listening";
  return true;
}

bool ChatServer::stopListen() {
  emit closeClient();

  if (this->isListening()) {
    qDebug() << "stop listening";
    this->close();
  }

  return true;
}

void ChatServer::incomingConnection(qintptr handle) {
  ChatClient *client = new ChatClient();
  client->setSocketDescriptor(handle);

  connect(this, &ChatServer::sendMsg, client, &ChatClient::writeMsg,
          Qt::QueuedConnection);
  connect(this, &ChatServer::closeClient, client, &ChatClient::stop,
          Qt::BlockingQueuedConnection);
  connect(client, &ChatClient::disconnected, this,
          &ChatServer::disconnectToClient, Qt::QueuedConnection);
  connect(client, &ChatClient::receiveMsg, this, &ChatServer::receiveFromClient,
          Qt::QueuedConnection);

  serverPrivate->tcpClients.append(client);

  client->start();

  // addPendingConnection(client);

  QHostAddress ip = client->peerAddress();
  qint16 port = client->peerPort();
  qDebug() << qPrintable(ip.toString()) << ":" << port
           << "connected successfully";
}

void ChatServer::setTcpServer(QString ip, int port) {
  serverPrivate->myServerAddress = ip;
  serverPrivate->myPort = port;
}

void ChatServer::sendToClient(int index, QByteArray &msg) {}

void ChatServer::sendToAllClient(QByteArray &msg) {
  for (int i = 0; i < serverPrivate->tcpClients.size(); ++i) {
    emit sendMsg(msg);
  }
}

void ChatServer::receiveFromClient(const QByteArray &rawMsg) {
  ChatClient *client = qobject_cast<ChatClient *>(sender());

  QString strIP = client->peerAddress().toString();
  QString strPort = QString::number(client->peerPort());

  emit receiveMsg(strIP, strPort, rawMsg);
}

void ChatServer::disconnectToClient() {
  ChatClient *client = qobject_cast<ChatClient *>(sender());

  qDebug() << "a client had disconnected";

  serverPrivate->tcpClients.removeOne(client);

  client->deleteLater();

  qDebug() << "chatclients number : " << serverPrivate->tcpClients.size();
}
